<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。
//  JCAT 由中国团队开发维护，是一个国际性的项目。
//  正在使用的这个版本是：0.3.1 / SVN信息：$Id: class.JCAT_Controller.php 1119 2008-10-25 03:55:26Z alee $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [HTTP下载] http://jcat.JeCat.cn/download
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.cn/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.cn/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/



JCAT_Package::ImportInterface('JCAT_IController',JCAT::PACKAGE_MVC) ;


define('MSGMVC','MSGMVC') ;
define('MSGMVC_OK','MSGMVC_OK') ;
define('MSGMVC_BAD','MSGMVC_BAD') ;
define('MSGMVC_DEBUG','MSGMVC_DEBUG') ;


interface JCAT_IHTTPPublicController
{}

/**
 * What's this Class ?
 *
 * @author		alee
 * @access		public
 */
abstract class JCAT_Controller extends JCAT_EventProcessor implements JCAT_IController
{


	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$sName=null		string				What's this Parameter ?
	 * @param	$aParent=null		JCAT_IController	What's this Parameter ?
	 * @return	void
	 */
	public function JCAT_Controller( $sName=null, JCAT_IController $aParent=null ) 
	{
		if($sName===null)
		{
			$sName = get_class($this) ;
		}
		
		JCAT_ASSERT::ASSERT_STRING($sName) ;
		$this->sName = $sName ;
		$this->aParentController = $aParent ;
		
		$this->aViewContainer = new _JCAT_MVCObjectContainer('JCAT_IView') ;
		$this->aDocumentContainer = new _JCAT_MVCObjectContainer('JCAT_IDocument',true) ;
		$this->aControllerContainer = new _JCAT_MVCObjectContainer('JCAT_IController') ;
		
		$this->aAuthenticator = new JCAT_CommonAuthenticator() ;
		
		// 注册为全局实例
		self::RegisterGlobalController($this) ;
	}
	

	/**
	 * 初始化相关的 MVC 对象
	 * 
	 * @access	protected
	 * @return	void
	 */
	protected function Initialize()
	{
		// 在 派生类中 实现 此函数 
	}
	
	/**
	 * 彻底 销毁一个控制器 在  MVC 系统中的所有引用，以便在不需要该控制器时能够立刻回收：
	 *  父控制器 对该控制器的引用
	 *  视图 对该控制器的引用
	 *  ... ...
	 * 
	 * @access	public
	 * @return	void
	 */
	public function Destroy()
	{
		// 清除子控制器
		$this->aControllerContainer->DestroyAll() ;
		
		// 清除视图
		$this->aViewContainer->DestroyAll() ;
		
		// 清除文档
		$this->aDocumentContainer->DestroyAll() ;
		
		// 解除 父容器对象 的引用
		$aControllerParent = $this->GetParentController() ;
		if( $aControllerParent )
		{
			JCAT_ASSERT::ASSERT_INSTANCE($aControllerParent,'JCAT_IContainer') ;
			$aControllerParent->RemoveView($this) ;
		}
		
	}
	
	
	/**
	 * 将一个文档设置给视图
	 * 
	 * @access	public
	 * @param	$sDocumentGlobalName	string		what's this
	 * @param	$sViewGlobalName		string		what's this
	 * @static
	 * @return	void
	 */
	static public function SetDocumentToView($sDocumentGlobalName,$sViewGlobalName)
	{
		JCAT_ASSERT::ASSERT_STRING($sDocumentGlobalName) ;
		JCAT_ASSERT::ASSERT_STRING($sViewGlobalName) ;
		
		$aDocument = JCAT_Document::GetDocumentByGlobalName($sDocumentGlobalName) ;
		JCAT_ASSERT::ASSERT_INSTANCE($aDocument,'JCAT_IDocument',JCAT_Language::SentenceEx('无法通过全局名称取得文档：%s','JCAT',null,$sDocumentGlobalName)) ;
		
		$aView = JCAT_View::GetViewByGlobalName($sViewGlobalName) ;
		JCAT_ASSERT::ASSERT_INSTANCE($aView,'JCAT_IView',JCAT_Language::SentenceEx('无法通过全局名称取得视图：%s','JCAT',null,$sViewGlobalName)) ;
		
		$aView->SetDocument($aDocument) ;
	}
	
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$aController	self	What's this Parameter ?
	 * @param	$sRegName=''	string	What's this Parameter ?
	 * @static
	 * @return	old_value
	 */
	static public function RegisterGlobalController( self $aController, $sRegName='' )
	{
		JCAT_ASSERT::ASSERT_STRING($sRegName) ;
		$sName = ($sRegName==='')? $aController->GetName(): $sRegName ;
			
		$old_value = self::GetGlobalController($sName) ;
		self::$arrControllerGlobalInstances[$sName] = $aController ;
		return $old_value ;
	}
	
	/**
	 * 
	 *
	 * @access	public
	 * @param	$sName	string	What's this Parameter ?
	 * @return	self, null
	 */
	static public function GetGlobalController($sName)
	{
		JCAT_ASSERT::ASSERT_STRING($sName) ;
		return isset(self::$arrControllerGlobalInstances[$sName])? self::$arrControllerGlobalInstances[$sName]: null ;
	}
	

	/**
	 * 校验 视图控件中输入的数据
	 * 
	 * @access	public
	 * @return	bool
	 */
	public function VerifyViewData( $bVerifyAll=true )
	{
		$bRet = true ;
		
		// 迭代 视图， 对各个 视图进行数据校验
		$aViewIterator = $this->CreateViewIterator() ;
		$aViewIterator->First() ;
		while( !$aViewIterator->IsDone() )
		{
			$aView = $aViewIterator->Current() ;
			
			// 仅 Form 视图
			if( JCAT_Global::HasImplementedTo($aView,'JCAT_IViewForm') )
			{
				// 遇到错误的视图
				if( !$aView->VerifyData($bVerifyAll) )
				{
					if(!$bVerifyAll)
					{
						return false ;
					}
					else
					{
						$bRet = false ;
					}
				}
			}
			
			$aViewIterator->Next() ;
		}
		
		// 子控制器 视图校验
		if( !$this->VerifyViewDataForChildController($bVerifyAll) )
		{
			$bRet = false ;
		}
		
			
		return $bRet ;
	}
	
	
	/**
	 * 子控制器 视图校验
	 * 
	 * @access	protected
	 * @return	array
	 */
	protected function VerifyViewDataForChildController( $bVerifyAll=true )
	{
		$bRet = true ;
		
		// 迭代子控制器
		$aControllerIterator = $this->CreateControllerIterator() ;
		$aControllerIterator->First() ;
		while( !$aControllerIterator->IsDone() )
		{
			$aController = $aControllerIterator->Current() ;
			
			if( !$aController->VerifyViewData() )
			{
				if(!$bVerifyAll)
				{
					return false ;
				}
				else
				{
					$bRet = false ;				
				}
			}
			
			$aControllerIterator->Next() ;
		}
		
		return $bRet ;
	}

	/**
	 * 对 文档 和 视图  之间进行数据交换
	 *
	 * @access	public
	 * @param	$nExchangeWay=self::UICTRL_TO_DOC	int	交换方向
	 * @return	void
	 */
	public function ExchangeData( $nExchangeWay=JCAT_IViewForm::UICTRL_TO_DOC )
	{
		// 迭代 视图
		$aViewIterator = $this->CreateViewIterator() ;
		$aViewIterator->First() ;
		while( !$aViewIterator->IsDone() )
		{
			$aView = $aViewIterator->Current() ;
			
			// 仅 Form 视图
			if( JCAT_Global::HasImplementedTo($aView,'JCAT_IViewForm') )
			{
				$aView->ExchangeData($nExchangeWay) ;
			}
			
			$aViewIterator->Next() ;
		}
		
		// 子控制器 数据交换
		$this->ExchangeDataForChildView($nExchangeWay) ;
	}


	/**
	 * 子视图  数据交换
	 *
	 * @access	protected
	 * @param	$nExchangeWay=self::UICTRL_TO_DOC	int	交换方向
	 * @return	void
	 */
	protected function ExchangeDataForChildView( $nExchangeWay=JCAT_IViewForm::UICTRL_TO_DOC )
	{
		// 迭代子控制器
		$aControllerIterator = $this->CreateControllerIterator() ;
		$aControllerIterator->First() ;
		while( !$aControllerIterator->IsDone() )
		{
			$aController = $aControllerIterator->Current() ;
			$aController->ExchangeData($nExchangeWay) ;
			
			$aControllerIterator->Next() ;
		}
	}
	
	
	/**
	 * 应用数据
	 * 
	 * @access	public
	 * @return	bool
	 */
	public function OnApplication()
	{
		// 数据校验 失败
		if( !$this->VerifyViewData() )
		{
			// 显示 失败信息
			$aMsgQueue = $this->GetMessageQueue() ;
			if( $aMsgQueue->GetMessageCount() )
			{
				$aMsgQueue->PrintQueue() ;
			}

			return false ;
		}
		
		// 数据交换
		$this->ExchangeData() ;
		return true ;
	}
	
	///////// 实现 JCAT_IController 接口 ///////////////////////////////////////////////////////////////////////////////
	
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	JCAT_IController,null
	 */
	public function GetParentController(  )
	{ return $this->aParentController ; }


	/**
	 * 取回 顶级控制器
	 * 
	 * @access	public
	 * @return	JCAT_IController
	 */
	public function GetTopController(  )
	{
		$aController = $this ;		
		while( $aParent = $aController->GetParentController() )
		{
			$aController = $aParent ;
		}
		
		return $aController ;
	}

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	string
	 */
	public function GetName(  )
	{ return $this->sName ; }




	/**
	 * 设置消息队列
	 *
	 * @access	public
	 * @param	$aMessageQueue		JCAT_MessageQueue	What's this Parameter ?
	 * @return	old_value
	 */
	public function SetMessageQueue( JCAT_MessageQueue $aMessageQueue )
	{
		$old_value = $this->aMessageQueue ;
		$this->aMessageQueue = $aMessageQueue ;
		return $old_value ;
	}


	/**
	 * 取得 消息队列
	 *
	 * @access	public
	 * @return	JCAT_MessageQueue
	 */
	public function GetMessageQueue()
	{
		if( $this->aMessageQueue )
		{
			return $this->aMessageQueue ;
		}
		
		$aParent = $this->GetParentController() ;
		if( $aParent )
		{
			return $aParent->GetMessageQueue() ;
		}
		else
		{
			return null ;
		}
	}
	


	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$aController	JCAT_IController	What's this Parameter ?
	 * @param	$sName=null		string				What's this Parameter ?
	 * @return	void
	 */
	public function AddController(  JCAT_IController $aController, $sName=null ) 
	{ return $this->aControllerContainer->Add($aController,$sName) ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$sName	string	What's this Parameter ?
	 * @return	JCAT_IController
	 */
	public function GetController(  $sName )
	{ return $this->aControllerContainer->Get($sName) ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$sName		What's this Parameter ?
	 * @return	void
	 */
	public function RemoveController(  $sName )
	{ return $this->aControllerContainer->Remve($sName) ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	int
	 */
	public function GetCotronllorCount(  ) 
	{ return $this->aControllerContainer->GetObjectCount() ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	int
	 */
	public function ClearCotronllor(  ) 
	{ return $this->aControllerContainer->ClearObject() ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	JCAT_ArrayIterator
	 */
	public function CreateControllerIterator(  )
	{ return $this->aControllerContainer->CreateObjectIterator() ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	array
	 */
	public function CreateControllerMemento(  )
	{ return $this->aControllerContainer->CreateObjectMemento() ; }



	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	array $arrMemento		What's this Parameter ?
	 * @return	void
	 */
	public function SetControllerMemento(  array $arrMemento )
	{ return $this->aControllerContainer->SetObjectMemento($arrMemento) ; }
	
	
	
	
	


	///////// 实现 JCAT_IViewContainer 接口 ///////////////////////////////////////////////////////////////////////////////
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$aView		JCAT_IView		What's this Parameter ?
	 * @param	$sName=null	string			What's this Parameter ?
	 * @return	void
	 */
	public function AddView( JCAT_IView $aView, $sName=null )
	{ return $this->aViewContainer->Add($aView,$sName) ; }
	
	
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$sViewName	JCAT_IView		What's this Parameter ?
	 * @return	void
	 */
	public function RemoveView( JCAT_IView $aView )
	{ return $this->aViewContainer->Remve($aView) ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$sName	string	What's this Parameter ?
	 * @return	JCAT_IView
	 */
	public function GetView( $sName )
	{ return $this->aViewContainer->Get($sName) ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	int
	 */
	public function GetViewCount(  ) 
	{ return $this->aViewContainer->GetObjectCount() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	int
	 */
	public function ClearView(  )
	{ return $this->aViewContainer->ClearObject() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	JCAT_ArrayIterator
	 */
	public function CreateViewIterator(  )
	{ return $this->aViewContainer->CreateObjectIterator() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	array
	 */
	public function CreateViewMemento(  )
	{ return $this->aViewContainer->CreateObjectMemento() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$arrMemento	array	What's this Parameter ?
	 * @return	void
	 */
	public function SetViewMemento( $arrMemento )
	{ return $this->aViewContainer->SetObjectMemento(arrMemento) ; }



	///////// 实现 JCAT_IDocumentContainer 接口 ///////////////////////////////////////////////////////////////////////////////
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$aDocument		JCAT_IDocument	What's this Parameter ?
	 * @param	$sName=null		string			What's this Parameter ?
	 * @return	void
	 */
	public function AddDocument( JCAT_IDocument $aDocument, $sName=null )
	{ return $this->aDocumentContainer->Add($aDocument,$sName) ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$aDocument		JCAT_IDocument	What's this Parameter ?
	 * @return	void
	 */
	public function RemoveDocument( JCAT_IDocument $aDocument )
	{ return $this->aDocumentContainer->Remove($aDocument) ; }
	
	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$sName	string	What's this Parameter ?
	 * @return	JCAT_IDocument
	 */
	public function GetDocument( $sName )
	{ return $this->aDocumentContainer->Get($sName) ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	int
	 */
	public function GetDocumentCount(  ) 
	{ return $this->aDocumentContainer->GetObjectCount() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	int
	 */
	public function ClearDocument(  )
	{ return $this->aDocumentContainer->ClearObject() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	JCAT_ArrayIterator
	 */
	public function CreateDocumentIterator(  )
	{ return $this->aDocumentContainer->CreateObjectIterator() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @return	array
	 */
	public function CreateDocumentMemento(  )
	{ return $this->aDocumentContainer->CreateObjectMemento() ; }

	/**
	 * What's this Method ?
	 * 
	 * @access	public
	 * @param	$arrMemento	array	What's this Parameter ?
	 * @return	void
	 */
	public function SetDocumentMemento( $arrMemento )
	{
		JCAT_ASSERT::ASSERT_ISTHESE($arrMemento,array('array:JCAT_IDocument')) ;
		return $this->aDocumentContainer->SetObjectMemento() ;	
	}


	/**
	 * 取得 用户身份验证器
	 *
	 * @access	protected
	 * @param	
	 * @return	JCAT_CommonAuthenticator
	 */
	protected function GetAuthenticator()
	{
		return $this->aAuthenticator ;
	}



	/**
	 * 授权
	 *
	 * @access	public
	 * @return	bool
	 */
	public function Authenticate()
	{
		return JCAT_IdentityManager::Authenticate($this->GetAuthenticator()) ;
	}






	// 属性 ///////////////////////////////////////////////////////////////////////////////

	/**
	 * What's this Attribute ?
	 * 
	 * @access	private
	 * @var		_JCAT_MVCObjectContainer
	 */
	private $aViewContainer ;

	/**
	 * What's this Attribute ?
	 * 
	 * @access	private
	 * @var		_JCAT_MVCObjectContainer
	 */
	private $aDocumentContainer ;

	/**
	 * What's this Attribute ?
	 * 
	 * @access	private
	 * @var		_JCAT_MVCObjectContainer
	 */
	private $aControllerContainer ;

	/**
	 * What's this Attribute ?
	 * 
	 * @access	private
	 * @var		JCAT_IController
	 */
	private $aParentController ;

	/**
	 * 消息队列
	 * 
	 * @access	private
	 * @var		JCAT_MessageQueue
	 */
	private $aMessageQueue ;
	
	
	
	private $arrMethodMapping = array() ;
	
	
	static private $arrControllerGlobalInstances = array() ;

	/**
	 * 用户身份验证器
	 * 
	 * @access	private
	 * @var		JCAT_CommonAuthenticator
	 */
	private $aAuthenticator = null ;
}

JCAT_Package::ImportInterface('JCAT_IViewForm',JCAT::PACKAGE_MVC) ;

?>